package com.qd.admin.controller;

import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.ApiResultWrapper;
import com.cdqidi.dto.DelDTO;
import com.cdqidi.exception.ApiException;
import com.cdqidi.valid.group.DefaultGroup;
import com.cdqidi.valid.group.UpdateGroup;
import com.qd.common.sys.annotation.OperatorInfo;
import com.qd.common.sys.domain.entity.meun.MenuDTO;
import com.qd.common.sys.enums.OperatorType;
import com.qd.common.sys.util.SecurityUtils;
import com.qd.system.service.menu.MenuHoldService;
import com.qd.system.service.menu.MenuService;
import com.qd.system.service.role.RoleMenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 菜单信息
 *
 * @author sjk
 */
@RestController
@Validated
@RequiredArgsConstructor
@Slf4j
public class MenuController {

    private final MenuService menuService;
    private final RoleMenuService roleMenuService;
    private final MenuHoldService menuHoldService;


    /**
     * 全部菜单
     *
     * @return 列表
     */
    @GetMapping(value = "/sys/sysMenu/list")
    public List<MenuDTO> list(MenuDTO menu) {
        return menuService.getAll(menu);
    }

    /**
     * 获取菜单详细信息
     *
     * @param menuId 菜单ID
     * @return 菜单信息
     */
    @GetMapping(value = "/sys/sysMenu/getById")
    public MenuDTO getById(@Validated @NotBlank(message = "菜单编号不能为空") String menuId) {
        return menuHoldService.getMenuInfoAndRoleInfo(menuId);
    }

    /**
     * 获取下级菜单
     *
     * @param menu 查询参数
     * @return 树形列表
     */
    @GetMapping(value = "/sys/sysMenu/getChildren")
    public List<MenuDTO> getChildren(MenuDTO menu) {
        if (null == menu) {
            throw new ApiException("查询参数不能为空");
        }
        if (!StringUtils.hasLength(menu.getParentId())) {
            throw new ApiException("菜单的父级ID不能为空");
        }
//        menu.setMenuStatus(Constants.STATUS_ENABLE);
        return menuHoldService.getChildren(menu);
    }

    /**
     * 加载对应角色菜单列表树
     *
     * @param roleId 角色ID
     * @return 角色对应的树形菜单
     */
    @GetMapping(value = "/sys/sysMenu/getMenuByRole")
    public Map<String, Object> getMenuByRoleId(@Validated @NotBlank(message = "角色ID不能为空") String roleId) {
        final List<MenuDTO> menus = menuHoldService.getMenuList(SecurityUtils.getLoginUser().getUserId());
        final Map<String, Object> map = new HashMap<>(2);
        map.put("checkedKeys", roleMenuService.getMenuStrByRoleId(roleId));
        map.put("menus", menuService.buildMenuTreeSelect(menus));
        return map;
    }

    /**
     * 新增菜单
     *
     * @return 菜单实体
     */
    @PreAuthorize("@ps.hasAnyPermissions('system:menu:save,system:menu:add')")
    @PostMapping(value = "/sys/sysMenu/save")
    @OperatorInfo(title = "添加菜单", operator = OperatorType.INSERT)
    public MenuDTO save(@Validated(DefaultGroup.class) @RequestBody MenuDTO menu) {
        if (null == menu.getAddTime()) {
            menu.setAddTime(LocalDateTime.now());
        }
        return menuService.saveMenu(menu);
    }

    /**
     * 修改菜单
     */
    @PreAuthorize("@ps.hasAnyPermissions('system:menu:edit,system:menu:edit')")
    @PutMapping(value = "/sys/sysMenu/update")
    @OperatorInfo(title = "修改菜单", operator = OperatorType.UPDATE)
    public ApiResultWrapper<Object> update(@Validated({UpdateGroup.class, DefaultGroup.class}) @RequestBody MenuDTO menu) {
        if (menu.getParentId().equals(menu.getMenuId())) {
            return ApiResult.error("不能选择自己");
        }
        if (null == menu.getUpdateTime()) {
            menu.setUpdateTime(LocalDateTime.now());
        }
        return menuService.updateMenu(menu);
    }

    /**
     * 删除菜单
     */
    @PreAuthorize("@ps.hasAnyPermissions('system:menu:delete,system:menu:delete')")
    @DeleteMapping(value = "/sys/sysMenu/delete")
    @OperatorInfo(title = "删除菜单", operator = OperatorType.DELETE)
    public ApiResultWrapper<Object> delete(@Validated @RequestBody DelDTO<String> delDTO) {
        final List<String> ids = delDTO.getIds();
        if (ids.size() == 1) {
            menuHoldService.removeById(ids.get(0));
        } else {
            menuHoldService.removeByIds(ids);
        }
        return ApiResult.success("删除成功");
    }

    /**
     * 菜单信息导出
     *
     * @param query 查询参数
     */
    @PreAuthorize("@ps.hasPermission('system:menu:export')")
    @GetMapping(value = "/sys/sysMenu/export")
    @OperatorInfo(title = "菜单信息导出", operator = OperatorType.EXPORT)
    public void export(MenuDTO query) {
        long startTime = System.currentTimeMillis();
        menuService.export(query);
        long endTime = System.currentTimeMillis();
        log.info("菜单信息导出,总耗时: {}s", (endTime - startTime) / 1000);

    }
}